
proc exec_cmd {args} {
    set cmd_str ""

    foreach arg $args {
        foreach line $arg {
            if {![regexp {^\s*$} $line]} {
                lappend cmd_str $line
            }
        }
    }
    puts $cmd_str
    eval $cmd_str
}

# $fpath = $fdir/$fname
proc fpath2fname {args} {
    if {[regexp {^.*/([^ /]+)\s*$} $args nc fname]} {
        return $fname
    } elseif {[regexp {^\s*([^ /]+)\s*$} $args nc fname]} {
        return $fname
    } else {
        return ""
    }
}

proc fpath2fdir {args} {
    if {[regexp {^\s*([^ ]+)/[^ /]+\s*$} $args nc fdir]} {
        return $fdir
    } elseif {[regexp {^\s*[^ /]+\s*$} $args]} {
        return "."
    } else {
        return ""
    }
}

proc unifpath {refdir line} {
    if {[file exists $refdir/$line]} {
        set fpath $refdir/$line 
    } elseif {[file exists $line]} {
        set fpath $line 
    } else {
        set fpath ""
    }

    if {$fpath!=""} {
        regsub {/./} $fpath "/" fpath
        regsub {\\}  $fpath "/" fpath
    }

    return $fpath
}

proc analyline {refdir line} {
    # delete comments space
    regsub {^\s+}       $line "" line
    regsub {\/\*.*\*\/} $line "" line
    regsub {\/\/.*$}    $line "" line
    regsub {\s+$}       $line "" line

    if {[regexp {^\s*$} $line]} {
        return ""
    }
    set sfile [unifpath $refdir $line]
    if {$sfile!=""} {
        return $sfile
    } elseif {[regexp {^\s*-f\s+([^ ]+)\s*$} $line nc nfpath]} {
        set nfpath [unifpath $refdir $nfpath]
        if {[file exists $nfpath]} {
            set fr [open $nfpath r]
            set rs {}
            while {![eof $fr]} {
                gets $fr nline
                set rs [concat $rs [analyline [fpath2fdir $nfpath] $nline]]
            }
            close $fr
            return $rs 
        } else {
            puts "Error:file list '$line' not exist!"
        }
    } elseif {[regexp {^\s*\+incdir\+(.+)\s*$} $line nc sfile]} {
        set sfile [unifpath $refdir $sfile]
        if {$sfile!=""} {
            return "-scan_for_includes $sfile"
        } else {
            puts "Error:directory '$line' not exist!"
        }
    } else {
        puts "Error:unkonw '$line'!"
        return ""
    }
}

proc add_rtl {} {
    global syn_list
    global add_files_basic_cmd
    global add_files_post

    set cmd_str $add_files_basic_cmd

    foreach f $syn_list {
        set cmd_str [concat $cmd_str [analyline "." $f]]
    }

    exec_cmd $cmd_str
    if {$add_files_post!=""} {
        foreach post $add_files_post {
            eval $post
        }
    }
}

proc cd_prj {} {
    eval cd [get_property directory [current_project]]
}

proc disp {} {
    puts "Vivado Extended Commands"
    puts {
    Script commands are:

    disp
        display this information.

    add_rtl
        add files in syn_list.

    cd_prj
        cd current project directory.
    }
}

